<template>
  <div class="base-table custom-table">
    <el-auto-resizer>
      <template #default="{ height }">
        <el-table
          v-loading="tableHook.tableData.isLoading"
          :data="tableHook.tableData.list"
          :height="`${config.showPagination ? height - 50 : height}px`"
          :highlight-current-row="config.highlightCurrentRow"
          :row-style="config.rowStyle"
          :stripe="config.stripe"
          size="large"
          tooltip-effect="dark"
          :border="config.border"
          @selection-change="handleSelectionChange"
          @current-change="handleCurrentChange"
        >
          <!-- 多选 -->
          <el-table-column v-if="config.multiple" type="selection" width="55" />
          <template v-for="(item, index) in props.tableColumnList" :key="index">
            <!-- 序号 -->
            <el-table-column
              v-if="item.type === 'index'"
              :align="item.align || 'center'"
              :label="item.label"
              :width="item.width || 70"
              type="index"
            />
            <!-- 普通列写法 -->
            <el-table-column
              v-if="!item.type"
              :align="item.align || 'center'"
              :formatter="item.formatter"
              :label="item.label"
              :prop="item.value"
              :width="item.width"
              show-overflow-tooltip
            >
            </el-table-column>
            <!-- 插槽写法 -->
            <el-table-column
              v-if="item.type === 'slot'"
              :align="item.align || 'center'"
              :label="item.label"
              :width="item.width"
            >
              <template #default="scope">
                <slot :data="scope" :name="item.slotName"></slot>
              </template>
            </el-table-column>
          </template>
          <!-- 右侧操作 -->
          <el-table-column
            v-if="Object.keys(props.tableOperationList).length > 0"
            :align="props.tableOperationList.align || 'center'"
            :label="props.tableOperationList.label || '操作'"
            :width="props.tableOperationList.width"
          >
            <template #default="scope">
              <div class="base-table-operation">
                <template
                  v-for="(operationItem, operationIndex) in props
                    .tableOperationList.operation"
                  :key="operationIndex"
                >
                  <span
                    v-if="
                      operationItem.show ? operationItem.show(scope.row) : true
                    "
                    @click="
                      handleOperationCommand(operationItem.type, scope.row)
                    "
                    >{{ operationItem.label }}</span
                  >
                </template>
              </div>
            </template>
          </el-table-column>
          <template #empty> 暂无数据</template>
        </el-table>
        <div v-if="config.showPagination" class="base-table-pagination">
          <el-pagination
            v-model:current-page="tableHook.tableParams.currentPageNo"
            v-model:page-size="tableHook.tableParams.onePageCount"
            :total="tableHook.tableData.total"
            background
            prev-text="上一页"
            next-text="下一页"
            layout="total,prev,pager,next"
            @current-change="handlePageCurrentChange"
          >
          </el-pagination>
        </div>
      </template>
    </el-auto-resizer>
  </div>
</template>

<script setup lang="ts">
import useTableData from './hooks/useTableData'
import type { TableColumnList, TableConfig, TableOperationList } from './types'

const props = withDefaults(
  defineProps<{
    tableConfig: TableConfig
    tableColumnList?: TableColumnList[]
    tableOperationList?: TableOperationList
  }>(),
  {
    tableConfig: () => ({}),
    tableColumnList: () => [],
    tableOperationList: () => ({})
  }
)

const emit = defineEmits([
  'baseTableQuery',
  'baseTableReset',
  'baseTableOperation',
  'baseTableSelectionChange',
  'baseTableCurrentChange'
])

// 列表默认配置
const defaultTableConfig: TableConfig = {
  apiFunc: '',
  apiFuncName: '',
  stripe: false,
  highlightCurrentRow: false,
  multiple: false,
  showPagination: true,
  rowStyle: {
    height: '56px'
  },
  border: true
}

// 合并配置项
const config = computed(() =>
  Object.assign(defaultTableConfig, props.tableConfig)
).value

// 列表hook
const tableHook = useTableData(config.apiFunc, config.apiFuncName, true)

// 查询
const handleTableQuery = (queryData: object) => {
  tableHook.setParams(queryData)
  emit('baseTableQuery')
}

// 重置
const handleTableReset = (queryData: object) => {
  tableHook.handleTableReset(queryData)
  emit('baseTableReset')
}

// 分页
const handlePageCurrentChange = (val: object) => {
  tableHook.setCurrentPage(val)
}

// 操作
const handleOperationCommand = (...args: any[]) => {
  emit('baseTableOperation', ...args)
}

// 多选
const handleSelectionChange = (...args: any[]) => {
  emit('baseTableSelectionChange', ...args)
}

// 行高亮单选
const handleCurrentChange = (...args: any[]) => {
  emit('baseTableCurrentChange', ...args)
}

// 初始化
const handleTableInit = () => {
  tableHook.handleTableInit()
}

// 设置假数据
const handleSetTableFakeData = (data: any) => {
  tableHook.tableData.list = data
}

// 暴露属性
defineExpose({
  tableData: computed(() => tableHook.tableData.list),
  handleTableQuery,
  handleTableReset,
  handleTableInit,
  handleSetTableFakeData
})
</script>

<style lang="scss" scoped>
.base-table {
  width: 100%;
  height: 100%;
  background-color: #fff;

  &-operation {
    font-size: 16px;
    color: #1890ff;

    span {
      cursor: pointer;
    }

    span:not(:last-child) {
      margin-right: 10px;
    }
  }

  &-pagination {
    width: 100%;
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}
</style>
